package com.pmmaster.admin.filters;


import com.alibaba.fastjson.JSON;
import com.pmmaster.common.api.Result;
import com.pmmaster.common.utils.CommonUtil;
import com.pmmaster.service.AdminService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.util.AntPathMatcher;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;

@WebFilter(filterName = "ApiAccessFilter", urlPatterns = "/*")
public class AppAccessFilter implements Filter {
    private Logger logger = LoggerFactory.getLogger(AppAccessFilter.class);

    /**
     * 不校验的权限
     */
    private String[] NO_CHECK = {"/login", "/verify/**"};

    @Value("${jwt.tokenHeader}")
    private String tokenHeader;

    @Value("${jwt.tokenHead}")
    private String tokenHead;

    @Value("${super_users}")
    private Integer[] super_users;

    @Autowired
    private AdminService adminService;

    @Override
    public void init(FilterConfig filterConfig) {
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        if (Arrays.asList("OPTION").contains(request.getMethod()) || noNeedCheck(request.getRequestURI())) {
            //不需要检测的
            filterChain.doFilter(servletRequest, servletResponse);
        } else {
            long start = System.currentTimeMillis(); // 请求进入时间
            logger.info("[Api Access] start. uri: {}, method: {}, client: {}", request.getRequestURI(), request.getMethod(), CommonUtil.getIpAddr(request));
            //注入当前授权用户
            request.getSession().setAttribute("loginUser", adminService.getLoginUser(request, tokenHead, tokenHeader));
            if (canAccess(request)) {
                //确定已授权
                filterChain.doFilter(servletRequest, servletResponse);
                logger.info("[Api Access]   end. duration: {}ms", System.currentTimeMillis() - start);
            } else {
                PrintWriter writer = null;
                HttpServletResponse response = (HttpServletResponse) servletResponse;
                response.setCharacterEncoding("UTF-8");
                response.setContentType("application/json; charset=utf-8");
                try {
                    writer = response.getWriter();
                    response.setStatus(HttpStatus.FORBIDDEN.value());
                    writer.print(JSON.toJSONString(Result.forbidden(request.getRequestURI() + " :没有权限")));
                } catch (IOException e) {
                    logger.error("拦截器输出流异常" + e);
                } finally {
                    if (writer != null) {
                        writer.close();
                    }
                }
            }
        }
    }

    /**
     * 来访请求是否需要验证
     *
     * @param requestURI
     * @return
     */
    private boolean noNeedCheck(String requestURI) {
        AntPathMatcher path = new AntPathMatcher();
        for (String reg : NO_CHECK) {
            if (path.match(reg, "/" + requestURI)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 权限判断
     *
     * @param request
     * @return
     */
    private boolean canAccess(HttpServletRequest request) {
        return adminService.checkPermission(request, super_users);
    }

    @Override
    public void destroy() {

    }
}
